package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.service.CartService;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.client.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@SuppressWarnings("all")
public class CartServiceImpl implements CartService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ProductFeignClient productFeignClient;
    /**
     * 添加购物车
     * @param skuId
     * @param userId
     * @param skuNum
     */
    @Override
    public void addToCart(Long skuId, String userId, Integer skuNum) {
        //定义Key
        String cartKey=getKey(userId);
        //定义商品对象
        CartInfo cartInfo=null;
        //获取购物车列表
        BoundHashOperations<String,String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        //查看购物车里面是否已经有同一件商品
        if (boundHashOperations.hasKey(skuId.toString())){
            cartInfo = boundHashOperations.get(skuId.toString());
            cartInfo.setSkuNum(cartInfo.getSkuNum()+skuNum);
            cartInfo.setIsChecked(1);
            cartInfo.setSkuPrice(productFeignClient.getSkuPrice(skuId));
            cartInfo.setUpdateTime(new Date());
        }else {
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            cartInfo=new CartInfo();
            //  给表的字段赋值！
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
            cartInfo.setSkuPrice(skuInfo.getPrice());
        }
        boundHashOperations.put(skuId.toString(),cartInfo);
    }

    /**
     * 展示购物车-合并版本
     * @param userId
     * @param userTempId
     * @return
     */
    @Override
    public List<CartInfo> getCartList(String userId, String userTempId) {
        //定义未登录购物车
        List<CartInfo> nologinCartList=null;
        if (!StringUtils.isEmpty(userTempId)){
            String key = getKey(userTempId);
            nologinCartList= redisTemplate.boundHashOps(key).values();
        }
        //表示未登录状态
        if (StringUtils.isEmpty(userId)&&!CollectionUtils.isEmpty(nologinCartList)){
            nologinCartList.sort((o1,o2)->{
                return DateUtil.truncatedCompareTo(o2.getUpdateTime(),o1.getUpdateTime(), Calendar.SECOND);
            });
            return nologinCartList;
        }
        //  登录状态
        List<CartInfo> LoginCartInfoList = null;
        //  先获取到登录购物车的key
        String cartKey = getKey(userId);
        //  合并
        BoundHashOperations<String, String, CartInfo>  boundHashOperations = redisTemplate.boundHashOps(cartKey);
        //  判断购物车中的field
        //  boundHashOperations.hasKey(skuId.toString);
        if (!CollectionUtils.isEmpty(nologinCartList)){
            //  循环遍历未登录购物车集合
            nologinCartList.stream().forEach(cartInfo -> {
                //  在未登录购物车中的skuId 与登录的购物车skuId 相对  skuId = 17 18
                if (boundHashOperations.hasKey(cartInfo.getSkuId().toString())){
                    //  合并业务逻辑 : skuNum + skuNum 更新时间
                    CartInfo loginCartInfo = boundHashOperations.get(cartInfo.getSkuId().toString());
                    loginCartInfo.setSkuNum(loginCartInfo.getSkuNum()+cartInfo.getSkuNum());
                    loginCartInfo.setUpdateTime(new Date());
                    //  最新价格
                    loginCartInfo.setSkuPrice(productFeignClient.getSkuPrice(cartInfo.getSkuId()));
                    //  选中状态合并！
                    if (cartInfo.getIsChecked().intValue()==1){
                        loginCartInfo.setIsChecked(1);
                    }
                    //  修改缓存的数据：    hset key field value
                    boundHashOperations.put(cartInfo.getSkuId().toString(),loginCartInfo);
                }else {
                    //  直接添加到缓存！    skuId = 19
                    cartInfo.setUserId(userId);
                    cartInfo.setCreateTime(new Date());
                    cartInfo.setUpdateTime(new Date());
                    boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
                }
            });
            //  删除未登录购物车数据！
            redisTemplate.delete(getKey(userTempId));
        }
        //  获取到合并之后的数据：
        LoginCartInfoList = redisTemplate.boundHashOps(cartKey).values();
        if (CollectionUtils.isEmpty(LoginCartInfoList)){
            return new ArrayList<>();
        }
        //  设置合并之后的排序结果！
        LoginCartInfoList.sort(((o1, o2) -> {
            return DateUtil.truncatedCompareTo(o2.getUpdateTime(),o1.getUpdateTime(), Calendar.SECOND);
        }));
        return LoginCartInfoList;
    }

    /**
     * 删除购物车
     * @param skuId
     * @param userId
     */
    @Override
    public void deleteCart(Long skuId, String userId) {
        redisTemplate.boundHashOps(getKey(userId)).delete(skuId.toString());
    }

    /**
     * 根据用户Id 查询购物车列表
     * @param userId
     * @return
     */
    @Override
    public List<CartInfo> getCartCheckedList(String userId) {
            //  获取的选中的购物车列表！
            String cartKey = getKey(userId);
            //  获取到购物车集合数据：
            List<CartInfo>  cartInfoList = redisTemplate.opsForHash().values(cartKey);
            List<CartInfo> cartInfos=null;
            if (!CollectionUtils.isEmpty(cartInfoList)) {
                    cartInfos = cartInfoList.stream().filter(cartInfo -> {
                    //  再次确认一下最新价格
                    cartInfo.setSkuPrice(productFeignClient.getSkuPrice(cartInfo.getSkuId()));
                    return cartInfo.getIsChecked().intValue() == 1;
                }).collect(Collectors.toList());
            }
            //  返回数据
            return cartInfos;
        }


    /**
     * 更新选中状态
     * @param userId
     * @param skuId
     * @param isChecked
     */
    @Override
    public void checkCart(String userId, Long skuId, Integer isChecked) {
        //获取数据列表
        BoundHashOperations<String,String,CartInfo> boundHashOps = redisTemplate.boundHashOps(getKey(userId));
        if (boundHashOps.hasKey(skuId.toString())){
            CartInfo cartInfo = boundHashOps.get(skuId.toString());
            //更新状态
            cartInfo.setIsChecked(isChecked);
            boundHashOps.put(skuId.toString(),cartInfo);
        }

    }

/**
     * 展示购物车-未合并版本
     * @param userId
     * @param userTempId
     * @return
     */
//    @Override
//    public List<CartInfo> getCartList(String userId, String userTempId) {
//        List<CartInfo> cartInfoList=null;
//        //获取临时用户的购物车列表
//        if (!StringUtils.isEmpty(userTempId)){
//            String key = getKey(userTempId);
//            cartInfoList= redisTemplate.boundHashOps(key).values();
//        }
//        //获取用户的购物车列表
//        if (!StringUtils.isEmpty(userId)){
//            String key = getKey(userId);
//            cartInfoList= redisTemplate.boundHashOps(key).values();
//        }
//        //排序updateTime
//        if (!CollectionUtils.isEmpty(cartInfoList)){
//            cartInfoList.sort((o1,o2)->{
//                return DateUtil.truncatedCompareTo(o2.getUpdateTime(),o1.getUpdateTime(), Calendar.SECOND);
//            });
//        }
//        return cartInfoList;
//    }

    /**
     * 获取操作购物车的Key
     * @param userId
     * @return
     */
    private String getKey(String userId) {
        return RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX;
    }
}
